package com.example.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.auth.consts.IndexConst;
import com.example.auth.entity.SysMenu;
import com.example.auth.entity.SysRole;
import com.example.auth.entity.SysRoleMenu;
import com.example.auth.entity.dto.AssignMenuDTO;
import com.example.auth.entity.dto.SysRoleCreateDTO;
import com.example.auth.entity.dto.SysRoleEditDTO;
import com.example.auth.entity.dto.SysRoleQueryDTO;
import com.example.auth.entity.vo.SysRoleQueryVO;
import com.example.auth.exception.LyException;
import com.example.auth.mapper.ISysRoleMapper;
import com.example.auth.mapper.SysMenuMapper;
import com.example.auth.service.SysRoleService;
import com.example.auth.mapper.SysRoleMapper;
import com.example.auth.utils.MenuHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author SIE
* @description 针对表【sys_role(角色)】的数据库操作Service实现
* @createDate 2023-07-07 13:05:31
*/
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole>
    implements SysRoleService{

    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Override
    public Page<SysRoleQueryVO> selectRolePage(Long pageNum, Long pageSize, SysRoleQueryDTO sysRoleQueryDTO) {
        Page<SysRoleQueryVO> sysRolePage = new Page<>(pageNum, pageSize);
        return sysRoleMapper.selectRolePage(sysRolePage,sysRoleQueryDTO);
    }

    @Override
    public void insertRole(SysRoleCreateDTO sysRoleCreateDTO) {
        if(ObjectUtils.isEmpty(sysRoleCreateDTO)){
            throw new LyException("请求对象不能为空");
        }
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getRoleName,sysRoleCreateDTO.getRoleName());
        SysRole sysRole = sysRoleMapper.selectOne(wrapper);
        if(!ObjectUtils.isEmpty(sysRole)){
            throw new LyException("该角色已存在");
        }
        sysRole = ISysRoleMapper.INSTANCT.sysRoleCreateDTOToSysRole(sysRoleCreateDTO);
        sysRoleMapper.insert(sysRole);
    }

    @Override
    public SysRoleQueryVO getRoleById(Long id) {
        SysRole sysRole = sysRoleMapper.selectById(id);
        return  ISysRoleMapper.INSTANCT.sysRoleToSysRoleQueryVO(sysRole);
    }

    @Override
    public void updateRole(SysRoleEditDTO sysRoleEditDTO) {
        if(ObjectUtils.isEmpty(sysRoleEditDTO)){
            throw new LyException("请求对象不能为空");
        }
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getRoleName,sysRoleEditDTO.getRoleName());
        SysRole sysRole = sysRoleMapper.selectOne(wrapper);
        if(!ObjectUtils.isEmpty(sysRole) && !sysRoleEditDTO.getId().equals(sysRole.getId())){
            throw new LyException("该角色已存在，请重新输入角色名");
        }
        sysRole = ISysRoleMapper.INSTANCT.sysRoleEditDTOToSysRole(sysRoleEditDTO);
        sysRoleMapper.updateById(sysRole);
    }

    @Transactional(rollbackFor = {Throwable.class})
    @Override
    public void removeRoleById(Long id) {
        //删除用户角色表数据
        sysRoleMapper.removeRoleUserById(id);
        //删除角色数据
        sysRoleMapper.deleteById(id);
        //删除角色菜单数据
        sysRoleMapper.deleteRoleMenuByRoleId(id);
    }

    @Transactional(rollbackFor = {Throwable.class})
    @Override
    public void removeBatch(List<Long> idList) {
        sysRoleMapper.batchRemoveRoleUserById(idList);
        sysRoleMapper.batchDeleteRoleMenuByRoleId(idList);
        sysRoleMapper.deleteBatchIds(idList);

    }

//    @Transactional(rollbackFor = {"Thow"})
    @Override
    public void updateRoleStatus(Long roleId, Long status) {
        sysRoleMapper.updateRoleStatus(roleId,status);
        SysRole sysRole = sysRoleMapper.selectById(roleId);
        UpdateWrapper<SysRole> wrapper = new UpdateWrapper<>();
        if(status == 1){
            wrapper.set("effective_time",new Date());
            wrapper.set("invalid_time",null);
        }else if(status == 0){
            wrapper.set("invalid_time",new Date());
        }
        wrapper.eq("id",sysRole.getId());
        sysRoleMapper.update(sysRole,wrapper);
    }

    @Override
    public List<SysMenu> findSysMenuByRoleId(Long roleId) {
        //查询有效菜单
        List<SysMenu> sysMenuList = sysMenuMapper.selectList(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getStatus, IndexConst.STATUS_OPEN));
        List<SysRoleMenu> sysRoleMenuList = sysRoleMapper.selectRoleMenuByRoleId(roleId);
        List<Long> menuIds = sysRoleMenuList.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
        for(SysMenu sysMenu: sysMenuList){
            sysMenu.setSelect(menuIds.contains(sysMenu.getId()));
        }
        return MenuHelper.buildTree(sysMenuList);
    }

    @Transactional(rollbackFor = {Throwable.class})
    @Override
    public void doAssign(AssignMenuDTO assignMenuDTO) {
        //先删除再插入
        Long roleId = assignMenuDTO.getRoleId();
        sysRoleMapper.deleteRoleMenuByRoleId(roleId);
        List<Long> menuIdList = assignMenuDTO.getMenuIdList();
        if(CollectionUtils.isEmpty(menuIdList)){
            return;
        }
        sysRoleMapper.insertBatch(roleId,menuIdList);
    }


}




